<?php

namespace app\api\services;

use app\api\cache\Marketing;
use app\api\consDir\CommunityConst;
use app\common\libs\Singleton;
use app\common\models\Card\Card;
use app\common\models\Card\CardOrder;
use app\common\models\Card\CardUser;
use app\common\models\Community\Community;
use app\common\models\Community\CommunityUser;
use app\common\models\Member\Member;
use think\Exception;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Log;

class CardService
{
    use Singleton;

    /**
     * @param $userId
     * @param $status
     * @param $page
     * @param $pageSize
     * @return array
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function orderList($userId, $status, $page, $pageSize): array
    {
        $where = [
            ['user_id', '=', $userId]
        ];
        if (is_numeric($status)) {
            $where[] = ['status', '=', $status];
        }
        $list = CardOrder::getInstance()
            ->where($where)
            ->page($page, $pageSize)
            ->order('id desc')
            ->select();
        if (empty($list)) {
            return [];
        }
        return $list->toArray();
    }


    /**
     * @throws ModelNotFoundException
     * @throws DataNotFoundException
     * @throws DbException
     */
    public function payCallback($payInfo): bool
    {
        $order = CardOrder::getInstance()->where('order_no', $payInfo['orderNo'])->find();
        if (empty($order)) {
            return false;
        }
        if ($payInfo['payPrice'] > 0 && $payInfo['payStatus'] == 3) {
            $msg = '会员卡订单抵扣' . $payInfo['payPrice'];
            MemberService::getInstance()->addFinanceLog($payInfo['userId'], 'pay_card', $payInfo['payPrice'], 1, $msg, $payInfo['orderNo']);
        }
        $where = [
            ['order_no', '=', $payInfo['orderNo']],
            ['status', '=', 0] //未支付
        ];
        $ret = CardOrder::getInstance()->where($where)->update(['status' => 1, 'pay_at' => date('Y-m-d H:i:s')]);
        if (!$ret) {
            return false;
        }
        $card = Card::getInstance()->where('id',$order['cardId'])->find();
        if(empty($card)){
            return false;
        }

        $typeName = $this->cardType($payInfo['userId'],$card);

        //减库存
        Card::getInstance()->where('id',$order['cardId'])->dec('stock', 1)->update();

        $where = [
            ['user_id','=',$payInfo['userId']],
            ['card_id','=',$order['cardId']],
        ];
        $cardUser = CardUser::getInstance()->where($where)->find();
        //time_type 1=》7天 ，2=》一个月，3=》三个月，4=》一年，5=》无期限
        $timeArr = [
            1 => 7,
            2 => 30,
            3 => 90,
            4 => 365,
            5 => 10000
        ];
        $dayNum = $timeArr[$card['timeType']] ?? 0;
        //会员卡不存在
        if(empty($cardUser)){
            $data = [
                'user_id' => $payInfo['userId'],
                'expire_at' => date('Y-m-d 23:59:59', strtotime('+' . $dayNum . ' day')),
                'card_type' => $card['type'],
                'card_id' => $card['id'],
                'card_title' => $card['title'],
                'card_time_type' => $card['timeType']
            ];
            CardUser::getInstance()->insert($data);
        }else{
            //会员卡存在
            if($cardUser->expireAt < date('Y-m-d H:i:s')){
                //过期
                $cardUser->expireAt = date('Y-m-d 23:59:59', strtotime('+' . $dayNum . ' day'));
            }else{
                //未过期
                $cardUser->expireAt = date('Y-m-d 23:59:59', strtotime('+' . $dayNum . ' day',strtotime($cardUser->expireAt)));
            }
            $cardUser->save();
        }

        if ($order['sendGxz'] > 0) {
            $msg = $typeName.'会员卡，赠送贡献值，订单号' . $payInfo['orderNo'];
            MemberService::getInstance()->addFinanceLog($payInfo['userId'], 'card_buy', $order['sendGxz'], 7, $msg, $payInfo['orderNo']);
        }

        if ($order['sendDeduction'] > 0) {
            $msg = $typeName.'会员卡';
            MemberService::getInstance()->addFinanceLog($payInfo['userId'], 'card_add', $order['sendDeduction'], 8, $msg, $payInfo['orderNo']);
        }
        $member = Member::getInstance()->where('id', $payInfo['userId'])->find();
        $price = $payInfo['payPrice'];
        //0标准卡 1特殊卡
        if ($order['cardType'] == 0) {
            $standardConfig = Marketing::getKeyData('card', 'standard');
            if ($standardConfig['status'] == 1) {
                if ($member['inviteId'] > 0) {
                    $rate = $standardConfig['direct_open_rate'];
                    $bonus = bcmul($price, $rate * 0.01, 4);
                    $msg = '直推会员'.$typeName.'会员卡，获得收益' . $bonus;
                    //MemberService::getInstance()->addFinanceLog($member['inviteId'], 'card_direct_earnings', $bonus, 5, $msg, $payInfo['orderNo'],1,2);
                    MemberService::getInstance()->addFinanceLog($member['inviteId'], 'direct_member_earnings', $bonus, 5, $msg, $payInfo['orderNo'],1,2);
                }

                $partnerInfo = MemberService::getInstance()->getMyPartnerInfo($payInfo['userId']);
                if (!empty($partnerInfo)) {
                    $rate = $standardConfig['service_rate'];
                    $bonus = bcmul($price, $rate * 0.01, 4);
                    $msg = $typeName.'会员卡，获得服务商收益' . $bonus;
                    //MemberService::getInstance()->addFinanceLog($partnerInfo['partnerId'], 'card_service_earnings', $bonus, 5, $msg, $payInfo['orderNo'],1,2);
                    MemberService::getInstance()->addFinanceLog($partnerInfo['partnerId'], 'spread_service_earnings', $bonus, 5, $msg, $payInfo['orderNo'],1,2);
                }

                //加入分润池
                MemberService::getInstance()->profitPoolLog($payInfo['userId'], $price, $payInfo['orderNo'], $price, 7);

                //平级服务商
                $userPingMember = Member::getInstance()->where('id',$payInfo['userId'])->find();
                $myPartner = MemberService::getInstance()->getMyPartner($userPingMember);
                if ($myPartner) {
                    $rate  = $standardConfig['ping_service_rate'];
                    $bonus = bcmul($price, $rate*0.01, 4);
                    $msg   = $typeName.'会员卡，获得平级服务商收益' .$bonus ;
                    MemberService::getInstance()->addFinanceLog($myPartner['id'], 'ping_service_earnings', $bonus, 5, $msg, $payInfo['orderNo'],1,2);
                }

                //合伙人
                $commId = Community::getInstance()->where('comm_id', $member['commId'])->value('id');
                $where = [
                    ['community_id', '=', $commId],
                    ['community_status', '=', CommunityConst::PERMANENT_STATUS],
                ];
                $community = CommunityUser::getInstance()->where($where)->find();
                if ($standardConfig['partner_rate'] > 0 && !empty($community) && $community['userId']) {
                    $rate = $standardConfig['partner_rate'];
                    $bonus = bcmul($price, $rate * 0.01, 4);
                    $msg = $typeName.'会员卡，社区合伙人获得收益' . $bonus;
                    MemberService::getInstance()->addFinanceLog($community['userId'], 'spread_partner_earnings', $bonus, 5, $msg, $payInfo['orderNo'],1,2);
                }

                $agencyInfo = MemberService::getInstance()->getAgencyArr($member['provinceId'], $member['cityId'], $member['countryId'], $member['streetId']);

                //省代理
                if ($agencyInfo['provinceUid'] > 0) {
                    $rate = $standardConfig['province_rate'];
                    $bonus = bcmul($price, $rate * 0.01, 4);
                    $msg = '区域会员'.$typeName.'会员卡，获得收益' . $bonus;
                    //MemberService::getInstance()->addFinanceLog($agencyInfo['provinceUid'], 'province_earnings', $bonus, 5, $msg, $payInfo['orderNo'],1,2);
                    MemberService::getInstance()->addFinanceLog($agencyInfo['provinceUid'], 'province_user_earnings', $bonus, 5, $msg, $payInfo['orderNo'],1,2);
                }
                //市代理
                if ($agencyInfo['cityUid'] > 0) {
                    $rate = $standardConfig['city_rate'];
                    $bonus = bcmul($price, $rate * 0.01, 4);
                    $msg = '区域会员'.$typeName.'会员卡，获得收益' . $bonus;
                    //MemberService::getInstance()->addFinanceLog($agencyInfo['cityUid'], 'city_earnings', $bonus, 5, $msg, $payInfo['orderNo'],1,2);
                    MemberService::getInstance()->addFinanceLog($agencyInfo['cityUid'], 'city_user_earnings', $bonus, 5, $msg, $payInfo['orderNo'],1,2);
                }
                //区/县代理
                if ($agencyInfo['countryUid'] > 0) {
                    $rate = $standardConfig['area_rate'];
                    $bonus = bcmul($price, $rate * 0.01, 4);
                    $msg = '区域会员'.$typeName.'会员卡'.'，获得收益' . $bonus;
                    //MemberService::getInstance()->addFinanceLog($agencyInfo['countryUid'], 'area_earnings', $bonus, 5, $msg, $payInfo['orderNo'],1,2);
                    MemberService::getInstance()->addFinanceLog($agencyInfo['countryUid'], 'area_user_earnings', $bonus, 5, $msg, $payInfo['orderNo'],1,2);
                }
            }
        } else {
            $specialConfig = Marketing::getKeyData('card', 'special');
            if ($specialConfig['status'] == 1) {
                if ($member['inviteId'] > 0) {
                    $rate = $specialConfig['direct_open_rate'];
                    $bonus = bcmul($price, $rate * 0.01, 4);
                    $msg = '直推会员'.$typeName.'会员卡，获得收益' . $bonus;
                    //MemberService::getInstance()->addFinanceLog($member['inviteId'], 'card_direct_earnings', $bonus, 5, $msg, $payInfo['orderNo'],1,2);
                    MemberService::getInstance()->addFinanceLog($member['inviteId'], 'direct_member_earnings', $bonus, 5, $msg, $payInfo['orderNo'],1,2);
                }


                $partnerInfo = MemberService::getInstance()->getMyPartnerInfo($payInfo['userId']);
                if (!empty($partnerInfo)) {
                    $rate = $specialConfig['service_rate'];
                    $bonus = bcmul($price, $rate * 0.01, 4);
                    $msg = $typeName.'会员卡，获得服务商收益' . $bonus;
                    //MemberService::getInstance()->addFinanceLog($partnerInfo['partnerId'], 'card_service_earnings', $bonus, 5, $msg, $payInfo['orderNo'],1,2);
                    MemberService::getInstance()->addFinanceLog($partnerInfo['partnerId'], 'spread_service_earnings', $bonus, 5, $msg, $payInfo['orderNo'],1,2);
                }
            }
        }

        return true;
    }

    /**
     * @throws ModelNotFoundException
     * @throws DataNotFoundException
     * @throws DbException
     */
    public function cardType($userId, $card): string
    {
        $where = [
            ['user_id','=',$userId],
        ];
        $cardUser = CardUser::getInstance()->where($where)->order('card_time_type desc')->find();
        $orderTypeStr = '开通';
        if($cardUser){
            if($card['timeType'] == $cardUser['cardTimeType']){
                //续费
                $orderTypeStr = '续费';
            }
            if($card['timeType'] > $cardUser['cardTimeType']){
                //升级
                $orderTypeStr = '升级';
            }
        }
        return $orderTypeStr;
    }

    public function createOrder($userId, $card, $orderNo): bool
    {
        $where = [
            ['user_id','=',$userId],
        ];
        $cardUser = CardUser::getInstance()->where($where)->order('card_time_type desc')->find();
        $orderType = 0;
        if($cardUser){
            if($card['timeType'] == $cardUser['cardTimeType']){
                //续费
                $orderType = 1;
            }
            if($card['timeType'] > $cardUser['cardTimeType']){
                //升级
                $orderType = 2;
            }
        }

        CardOrder::getInstance()->startTrans();
        try {
            $data = [
                'user_id' => $userId,
                'order_no' => $orderNo,
                'pay_price' => $card['price'],
                'card_id' => $card['id'],
                'expire_at' => date('Y-m-d H:i:s', strtotime('+5 minutes')),
                'send_gxz' => $card['gxz'],
                'send_deduction' => $card['deduction'],
                'card_snapshot' => json_encode($card,256),
                'card_title' => $card['title'],
                'card_type' => $card['type'],
                'order_type' => $orderType,//0开通 1续费 2升级
            ];
            $order = CardOrder::getInstance()->insert($data);
            if (!$order) {
                return false;
            }
        } catch (\Exception $e) {
            CardOrder::getInstance()->rollback();
            return false;
        }
        CardOrder::getInstance()->commit();
        return true;
    }


    /**
     * @throws ModelNotFoundException
     * @throws DataNotFoundException
     * @throws DbException
     */
    public function getOrderInfo($orderNo, $uid): array
    {
        $where = [
            ['order_no', '=', $orderNo],
            ['user_id', '=', $uid],
        ];
        $order = CardOrder::getInstance()
            ->where($where)
            ->find();
        return empty($order) ? [] : $order->toArray();
    }

}
